/**
 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
 */
package com.ld.shieldsb.common.core.io;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.activation.MimetypesFileTypeMap;

import org.apache.commons.codec.digest.DigestUtils;

import com.ld.shieldsb.common.core.collections.ListUtils;
import com.ld.shieldsb.common.core.encryptor.EncodeUtils;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.core.util.os.OSType;
import com.ld.shieldsb.common.core.util.os.OSUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 文件操作工具类 实现文件的创建、删除、复制、压缩、解压以及目录的创建、删除、复制、压缩解压等功能
 * 
 * @author ThinkGem
 * @version 2015-3-16
 */
@Slf4j
public class FileUtils extends org.apache.commons.io.FileUtils {
    /**
     * 当前目录路径
     */
    public static final String CURRENT_WORK_DIR = System.getProperty("user.dir") + File.separator;

    /**
     * 复制单个文件，如果目标文件存在，则不覆盖
     * 
     * @param srcFileName
     *            待复制的文件名
     * @param descFileName
     *            目标文件名
     * @return 如果复制成功，则返回true，否则返回false
     */
    public static boolean copyFile(String srcFileName, String descFileName) {
        return copyFile(srcFileName, descFileName, false);
    }

    /**
     * 复制单个文件
     * 
     * @param srcFileName
     *            待复制的文件名
     * @param destFileName
     *            目标文件名
     * @param preserveFileDate
     *            保留源文件日期
     * @return 如果复制成功，则返回true，否则返回false
     */
    public static boolean copyFile(String srcFileName, String destFileName, boolean preserveFileDate) {
        File srcFile = new File(srcFileName);
        File destFile = new File(destFileName);

        try {
            copyFile(srcFile, destFile, preserveFileDate);
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    /**
     * 复制整个目录的内容，如果目标目录存在，则不覆盖
     * 
     * @param srcDirName
     *            源目录名
     * @param descDirName
     *            目标目录名
     * @return 如果复制成功返回true，否则返回false
     */
    public static boolean copyDirectory(String srcDirName, String descDirName) {
        return copyDirectory(srcDirName, descDirName, true);
    }

    /**
     * 复制整个目录的内容
     * 
     * @param srcDirName
     *            源目录名
     * @param descDirName
     *            目标目录名
     * @param preserveFileDate
     *            保留源文件日期
     * @return 如果复制成功返回true，否则返回false
     */
    public static boolean copyDirectory(String srcDirName, String descDirName, final boolean preserveFileDate) {
        File srcDir = new File(srcDirName);
        File destDir = new File(descDirName);
        try {
            copyDirectory(srcDir, destDir, preserveFileDate);
        } catch (IOException e) {
            log.error("", e);
            return false;
        }
        return true;

    }

    /**
     * 
     * 删除文件，可以删除单个文件或文件夹,注意此方法删除失败不会报错
     * 
     * @param fileName
     *            被删除的文件名
     * @return 如果删除成功，则返回true，否是返回false
     */
    public static boolean delete(String fileName) {
        File file = new File(fileName);
        return FileUtils.deleteQuietly(file);
    }

    /**
     * 批量删除文件
     * 
     * @Title delete
     * @author 吕凯
     * @date 2021年4月29日 下午6:40:45
     * @param files
     *            void
     */
    public static void delete(List<File> files) {
        for (File file : files) {
            try {
                Files.deleteIfExists(file.toPath());
            } catch (IOException e) {
                log.error("", e);
            }
        }

    }

    /**
     * 删除文件（如果删除后父目录为空则一并删除）
     * 
     * @Title deleteCaseParent
     * @author 吕凯
     * @date 2019年2月14日 上午11:20:14
     * @param filePath
     * @return boolean
     */
    public static boolean deleteCaseParent(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            File parentFile = file.getParentFile();
            File[] files = parentFile.listFiles();
            try {
                if (files.length == 1) {
                    if (Files.deleteIfExists(file.toPath())) {
                        deleteEmptyParent(parentFile);
                    }
                    return true;
                } else {
                    return Files.deleteIfExists(file.toPath());
                }
            } catch (IOException e) {
                log.error("", e);
            }
        }
        return false;
    }

    /**
     * 删除空的父目录
     * 
     * @Title deleteEmptyParent
     * @author 吕凯
     * @date 2019年2月14日 上午11:19:53
     * @param file
     *            void
     */
    public static void deleteEmptyParent(File file) {
        File[] files = file.listFiles();
        if (files.length == 0) {
            File parentFile = file.getParentFile();
            try {
                if (Files.deleteIfExists(file.toPath()) && parentFile != null) {
                    deleteEmptyParent(parentFile);
                }
            } catch (IOException e) {
                log.error("", e);
            }
        }
    }

    /**
     * 
     * 删除目录及目录下的文件
     * 
     * @param dirName
     *            被删除的目录所在的文件路径
     * @return 如果目录删除成功，则返回true，否则返回false
     */
    public static boolean deleteDirectory(String dirName) {
        File dirFile = new File(dirName);
        try {
            deleteDirectory(dirFile);
            return true;
        } catch (IOException e) {
            log.error("", e);
            return false;
        }

    }

    /**
     * 创建单个文件
     * 
     * @param descFileName
     *            文件名，包含路径
     * @return 如果创建成功，则返回true，否则返回false
     */
    public static boolean createFile(String descFileName) {
        File file = new File(descFileName);
        // 创建文件(实现与Unix上“ touch”实用程序相同的行为。它会创建一个大小为0的新文件，或者如果文件已经存在，则将其打开和关闭而不进行修改，而是更新文件的日期和时间。)
        try {
            touch(file);
            return true;
        } catch (IOException e) {
            log.error("", e);
        }
        return false;
    }

    /**
     * 创建目录
     * 
     * @param descDirName
     *            目录名,包含路径
     * @return 如果创建成功，则返回true，否则返回false
     */
    public static boolean createDirectory(String descDirName) {
        String descDirNames = descDirName;
        if (!descDirNames.endsWith(File.separator)) {
            descDirNames = descDirNames + File.separator;
        }
        File descDir = new File(descDirNames);
        if (descDir.exists()) {
            log.warn("目录 " + descDirNames + " 已存在!");
            return false;
        }
        // 创建目录
        return descDir.mkdirs();
    }

    /**
     * 写入文件（utf-8编码）
     * 
     * @Title writeToFile
     * @author 吕凯
     * @date 2019年3月12日 下午2:04:53
     * @param fileName
     * @param content
     *            void
     */
    public static boolean writeToFile(String fileName, String content) {
        return writeToFile(fileName, content, "utf-8", false);
    }

    /**
     * 写入文件直接覆盖
     * 
     * @Title writeToFile
     * @author 吕凯
     * @date 2019年3月12日 下午2:04:02
     * @param fileName
     *            文件名称
     * @param content
     *            写入内容
     * @param encoding
     *            编码 void
     */
    public static boolean writeToFile(String fileName, String content, String encoding) {
        return writeToFile(fileName, content, encoding, false);
    }

    /**
     * 
     * 以utf-8编码写入文件
     * 
     * @Title writeToFile
     * @author 吕凯
     * @date 2021年4月29日 下午6:31:33
     * @param fileName
     *            要写入的文件名称
     * @param content
     *            写入的文件内容
     * @param append
     *            是否追加
     * @return boolean
     */
    public static boolean writeToFile(String fileName, String content, boolean append) {
        return writeToFile(fileName, content, "utf-8", append);
    }

    /**
     * 
     * 写入文件
     * 
     * @Title writeToFile
     * @author 吕凯
     * @date 2021年4月29日 下午6:30:56
     * @param fileName
     *            要写入的文件名称
     * @param content
     *            写入的文件内容
     * @param encoding
     *            编码
     * @param append
     *            是否追加
     * @return boolean
     */
    public static boolean writeToFile(String fileName, String content, String encoding, boolean append) {
        try {
            FileUtils.write(new File(fileName), content, encoding, append);
            log.debug("文件 " + fileName + " 写入成功!");
            return true;
        } catch (IOException e) {
            log.error("文件 " + fileName + " 写入失败!", e);
        }
        return false;
    }

    /**
     * 根据图片Base64写入图片文件
     * 
     * @param filePath
     *            写入的文件路径及文件名
     * @param imageBase64
     *            图片Base64字符串
     */
    public static void convertBase64ToFile(String filePath, String imageBase64) {
        String base64 = imageBase64;
        if (imageBase64.startsWith("base64,")) { // 网页

            base64 = StringUtils.substringAfter(imageBase64, "base64,");
        }
        if (StringUtils.isBlank(base64)) {
            return;
        }
        byte[] data = EncodeUtils.decodeBase64(base64);

        File file = new File(filePath);
        try {
            FileUtils.writeByteArrayToFile(file, data);
        } catch (IOException e) {
            log.error("", e);
        }
    }

    /**
     * 本地文件（图片、excel等）转换成Base64字符串
     *
     * @param filePath
     */
    public static String convertFile2Base64(String filePath) {
        File file = new File(filePath);
        return convertFile2Base64(file);
    }

    public static String convertFile2Base64(File file) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            data = FileUtils.readFileToByteArray(file);
        } catch (IOException e) {
            log.error("", e);
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
        String base64Str = EncodeUtils.encodeBase642Str(data);
        return base64Str;
    }

    /**
     * 获取文件的md5值
     * 
     * @Title getFileMD5Hex
     * @author 吕凯
     * @date 2020年7月6日 上午9:36:33
     * @param filePath
     * @return String
     */
    public static String getFileMD5Hex(String filePath) {
        String md5Hex = null;
        // 读取图片字节数组
        try {
            md5Hex = DigestUtils.md5Hex(IOUtils.getFileInputStream(filePath));
        } catch (IOException e) {
            log.error("", e);
        }
        return md5Hex;
    }

    public static String getFileMD5Hex(File file) {
        String md5Hex = null;
        // 读取图片字节数组
        try {
            md5Hex = DigestUtils.md5Hex(IOUtils.getFileInputStream(file));
        } catch (IOException e) {
            log.error("", e);
        }
        return md5Hex;
    }

    public static String getFileMD5Hex(URL fileURL) {
        String md5Hex = null;
        // 读取图片字节数组
        try {
            md5Hex = DigestUtils.md5Hex(fileURL.openStream());
        } catch (IOException e) {
            log.error("", e);
        }
        return md5Hex;
    }

    /**
     * URL转换为Base64字符串
     * 
     * @Title convertFile2Base64
     * @author 吕凯
     * @date 2020年7月6日 上午9:22:30
     * @param fileURL
     *            文件url
     * @return String
     */
    public static String convertFile2Base64(URL fileURL) {
        byte[] data = null;

        // 打开链接
        try (InputStream inStream = fileURL.openStream();) {
            // 通过输入流获取图片数据
            data = IOUtils.toByteArray(inStream);
        } catch (IOException e) {
            log.error("", e);
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
        String base64Str = EncodeUtils.encodeBase642Str(data);
        return base64Str;
    }

    /**
     * 根据文件名的后缀获取文件内容类型
     * 
     * @return 返回文件类型
     */
    public static String getContentType(String fileName) {
        return new MimetypesFileTypeMap().getContentType(fileName);
    }

    /**
     * 修正路径，将 \\ 或 / 等替换为 File.separator
     * 
     * @param path
     *            待修正的路径
     * @return 修正后的路径
     */
    public static String path(String path) {
        String p = StringUtils.replace(path, "\\", "/");
        p = StringUtils.join(StringUtils.split(p, "/"), "/");
        if (!StringUtils.startsWithAny(p, "/") && StringUtils.startsWithAny(path, "\\", "/")) {
            p += "/";
        }
        if (!StringUtils.endsWithAny(p, "/") && StringUtils.endsWithAny(path, "\\", "/")) {
            p = p + "/";
        }
        if (path != null && path.startsWith("/")) {
            p = "/" + p; // linux下路径
        }
        return p;
    }

    /**
     * 获目录下的文件列表(只显示文件或目录)
     * 
     * @param dir
     *            搜索目录
     * @param searchDirs
     *            是否是搜索目录，true之搜索目录，false只搜索文件
     * @return 文件列表
     */
    public static List<String> findChildrenList(File dir, boolean searchDirs) {
        List<String> files = ListUtils.newArrayList();
        if (dir != null && dir.list() != null) {

            for (String subFiles : dir.list()) {
                File file = new File(dir + File.separator + subFiles);
                if ((searchDirs && file.isDirectory()) || (!searchDirs && !file.isDirectory())) {
                    files.add(file.getName());
                }
            }
        }
        return files;
    }

    /**
     * 获取文件名(带扩展名)
     * 
     * @param pathname
     *            文件路径名
     */
    public static String getFileName(String fileName) {
        return new File(fileName).getName();
    }

    /**
     * 获取文件名，不包含扩展名
     * 
     * @param fileName
     *            文件名
     * @return 例如：d:\files\test.jpg 返回：d:\files\test
     */
    public static String getFileNameWithoutExtension(String fileName) {
        if ((fileName == null) || (fileName.lastIndexOf('.') == -1)) {
            return null;
        }
        return fileName.substring(0, fileName.lastIndexOf('.'));
    }

    /**
     * 获取文件扩展名(返回小写)
     * 
     * @param pathname
     *            文件名
     * @return 例如：test.jpg 返回： jpg
     */
    public static String getFileExtension(String fileName) {
        if ((fileName == null) || (fileName.lastIndexOf('.') == -1) || (fileName.lastIndexOf('.') == fileName.length() - 1)) {
            return null;
        }
        return StringUtils.lowerCase(fileName.substring(fileName.lastIndexOf('.') + 1));
    }

    /**
     * 根据图片Base64获取文件扩展名
     * 
     * @param imageBase64
     * @return
     * @author ThinkGem
     */
    public static String getFileExtensionByImageBase64(String imageBase64) {
        String extension = null;
        String type = StringUtils.substringBetween(imageBase64, "data:", ";base64,");
        if (StringUtils.inStrArrIgnoreCase(type, "image/jpeg")) {
            extension = "jpg";
        } else if (StringUtils.inStrArrIgnoreCase(type, "image/gif")) {
            extension = "gif";
        } else {
            extension = "png";
        }
        return extension;
    }

    /**
     * 判断文件是否存在
     *
     * @param fileName
     * @return
     */
    public static boolean exists(String fileName) {
        File f = new File(fileName);
        return f.exists();
    }

    /**
     * 获取jar包的执行路径
     * 
     * @Title getJarExecPath
     * @author 吕凯
     * @date 2019年8月1日 下午3:05:52
     * @param clazz
     * @return String
     */
    public static String getJarExecPath(Class<?> clazz) {
        String path = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
        if (OSUtil.getOSType().equals(OSType.Windows)) {
            return path.substring(1);
        }
        return path;
    }

    /**
     * 根据完整文件名，得到文件所在目录
     *
     * @param filePath
     * @return
     */
    public static String getDirName(String filePath) {
        File f = new File(filePath);
        return f.getParent();
    }

    /**
     * 加载classPath下的属性文件
     *
     * @param fileName
     *            比如：“/properties/mail.properties”
     * @return
     * @throws Exception
     */
    public static Properties loadProperties(String fileName) {
        try (InputStream is = FileUtils.class.getResourceAsStream(fileName)) {
            Properties p = new Properties();
            p.load(is);
            return p;
        } catch (Exception e) {
            log.error("", e);
        }
        return null;
    }

    /**
     * 递归获取指定目录下的所有的文件（不包括文件夹）
     *
     * @return
     */
    public static List<File> getAllFiles(String dirPath) {
        File dir = new File(dirPath);

        ArrayList<File> files = new ArrayList<>();

        if (dir.isDirectory()) {
            File[] fileArr = dir.listFiles();
            if (fileArr != null) {

                for (int i = 0; i < fileArr.length; i++) {
                    File f = fileArr[i];
                    if (f.isFile()) {
                        files.add(f);
                    } else {
                        files.addAll(getAllFiles(f.getPath()));
                    }
                }
            }
        }
        return files;
    }

    /**
     * 获取指定目录下的所有下一级子目录(不递归)
     *
     * @param dirPath
     * @return
     */
    public static List<File> getAllDirectory(String dirPath) {
        return getAllDirectory(dirPath, false);
    }

    /**
     * 获取指定路径下的所有目录
     *
     * @param dirPath
     * @param isRecursive
     * @return
     */
    public static List<File> getAllDirectory(String dirPath, boolean isRecursive) {
        File dir = new File(dirPath);
        ArrayList<File> files = new ArrayList<>();
        if (dir.isDirectory()) {
            File[] fileArr = dir.listFiles();
            if (fileArr != null) {

                for (int i = 0; i < fileArr.length; i++) {
                    File f = fileArr[i];
                    if (f.isDirectory()) {
                        files.add(f);
                        if (isRecursive) {
                            files.addAll(getAllDirectory(f.getPath(), true));
                        }
                    }
                }
            }
        }
        return files;
    }

    /**
     * 获取指定目录下的所有文件(不包括子文件夹)
     *
     * @param dirPath
     * @return
     */
    public static List<File> getDirFiles(String dirPath) {
        File path = new File(dirPath);
        File[] fileArr = path.listFiles(File::isFile);
        return returnEmptyFileList(fileArr);
    }

    /**
     * 获取指定目录下特定文件后缀名的文件列表(不包括子文件夹)
     *
     * @param dirPath
     *            目录路径
     * @param suffix
     *            文件后缀
     * @return
     */
    public static List<File> getDirFiles(String dirPath, final String suffix) {
        File path = new File(dirPath);
        File[] fileArr = path.listFiles(file -> {
            String name = file.getName();
            String lowerName = name.toLowerCase();
            String lowerSuffix = suffix.toLowerCase();
            return file.isFile() && lowerName.endsWith(lowerSuffix);
        });
        return returnEmptyFileList(fileArr);
    }

    /**
     * 通过前缀得到指定文件夹下的文件列表
     *
     * @param dirPath
     *            目录路径
     * @param prefix
     *            前缀
     * @return
     */
    public static List<File> getDirFilesByPrefix(String dirPath, final String prefix) {
        File path = new File(dirPath);
        File[] fileArr = path.listFiles(file -> {
            String name = file.getName();
            String lowerName = name.toLowerCase();
            String lowerPrefix = prefix.toLowerCase();
            return file.isFile() && lowerName.startsWith(lowerPrefix);
        });

        return returnEmptyFileList(fileArr);
    }

    /**
     * 返回一个空文件集合
     * 
     * @Title returnEmptyFileList
     * @author 吕凯
     * @date 2021年4月30日 下午4:37:58
     * @param fileArr
     * @return List<File>
     */
    private static List<File> returnEmptyFileList(File[] fileArr) {
        return Arrays.asList(fileArr == null ? new File[0] : fileArr);
    }

    /**
     * 通过前缀后后缀获取符合条件的文件
     * 
     * @Title getDirFilesByPrefixAndSurfix
     * @author 吕凯
     * @date 2019年8月1日 下午3:10:42
     * @param dirPath
     *            目录路径
     * @param prefix
     *            前缀
     * @param surfix
     *            后缀
     * @return List<File>
     */
    public static List<File> getDirFilesByPrefixAndSurfix(String dirPath, final String prefix, final String surfix) {
        File path = new File(dirPath);
        File[] fileArr = path.listFiles(file -> {
            String name = file.getName();
            String lowerName = name.toLowerCase();
            String lowerPrefix = prefix.toLowerCase();
            String lowerSurfix = surfix.toLowerCase();
            return file.isFile() && lowerName.startsWith(lowerPrefix) && lowerName.endsWith(lowerSurfix);
        });
        return returnEmptyFileList(fileArr);
    }

    /**
     * 获取目录下某前缀并排除一部分前缀的文件
     * 
     * @Title getDirFilesByPrefix
     * @author 吕凯
     * @date 2019年8月1日 下午3:12:34
     * @param dirPath
     *            目录
     * @param prefix
     *            搜索的前缀
     * @param execludePrefix
     *            排除的前缀
     * @return List<File>
     */
    public static List<File> getDirFilesByPrefix(String dirPath, final String prefix, final String execludePrefix) {
        File path = new File(dirPath);
        File[] fileArr = path.listFiles(file -> {
            String name = file.getName();
            String lowerName = name.toLowerCase();
            String lowerPrefix = prefix.toLowerCase();
            String lowerExecludePrefix = execludePrefix.toLowerCase();
            return file.isFile() && lowerName.startsWith(lowerPrefix) && !lowerName.startsWith(lowerExecludePrefix);

        });
        return returnEmptyFileList(fileArr);
    }

    /**
     * 获取文件文本内容
     *
     * @param fileName
     *            待读取的完整文件名
     * @return 文件内容
     * @throws IOException
     */
    public static String read(String fileName) throws IOException {
        File f = new File(fileName);
        if (!f.exists()) {
            return null;
        }
        return read(f, "UTF-8");
    }

    /**
     * 获取文件文本内容
     *
     * @param f
     * @return
     * @throws IOException
     */
    public static String read(File f, String encoding) throws IOException {
        return FileUtils.readFileToString(f, encoding);
    }

    /**
     * 写文件
     *
     * @param fileName
     *            目标文件名
     * @param fileContent
     *            写入的内容
     * @return
     * @throws IOException
     */
    public static void write(String fileName, String fileContent) throws IOException {
        write(fileName, fileContent.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 写文件
     *
     * @param fileName
     *            完整文件名(类似：/usr/a/b/c/d.txt)
     * @param contentBytes
     *            文件内容的字节数组
     * @return
     * @throws IOException
     */
    public static void write(String fileName, byte[] contentBytes) throws IOException {
        File f = new File(fileName);
        FileUtils.writeByteArrayToFile(f, contentBytes);
    }

    /**
     * 写文件
     * 
     * @Title write
     * @author 吕凯
     * @date 2019年8月3日 下午2:31:00
     * @param fileName
     * @param fileContent
     * @param encoding
     * @throws IOException
     *             void
     */
    public static void write(String fileName, String fileContent, String encoding) throws IOException {
        File f = new File(fileName);
        org.apache.commons.io.FileUtils.write(f, fileContent, encoding);
    }

    /**
     * 
     * 追加内容到指定文件
     * 
     * @Title append
     * @author 吕凯
     * @date 2019年8月1日 下午3:16:51
     * @param fileName
     *            文件路径
     * @param fileContent
     *            文件内容
     * @param createFileIfNoExist
     *            如果文件不存在是否创建
     * @throws IOException
     *             void
     */
    public static void append(String fileName, String fileContent, boolean createFileIfNoExist) throws IOException {
        File f = new File(fileName);
        if (f.exists()) {
            try (RandomAccessFile rFile = new RandomAccessFile(f, "rw")) {
                byte[] b = fileContent.getBytes(StandardCharsets.UTF_8);
                long originLen = f.length();
                rFile.setLength(originLen + b.length);
                rFile.seek(originLen);
                rFile.write(b);
            }
        } else if (createFileIfNoExist) {
            write(fileName, fileContent);
        }
    }

    /**
     * 
     * 追加内容到指定文件(如果文件不存在则创建)
     * 
     * @Title append
     * @author 吕凯
     * @date 2019年8月1日 下午3:17:34
     * @param fileName
     *            文件路径
     * @param fileContent
     *            文件内容
     * @throws IOException
     *             void
     */
    public static void append(String fileName, String fileContent) throws IOException {
        append(fileName, fileContent, true);
    }

    /**
     * 创建(多级)目录，如果文件已存在则直接返回
     *
     * @param filePath
     *            完整的文件名(类似：/usr/a/b/c/d.xml)
     */
    public static boolean createDirs(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return false;
        }
        File parent = file.getParentFile();
        if (parent != null && !parent.exists()) {
            return parent.mkdirs();
        }
        return false;
    }

    /**
     * 移动文件
     *
     * @param fileNameFrom
     * @param fileNameTo
     * @throws IOException
     */
    public static void moveFile(String fileNameFrom, String fileNameTo) throws IOException {
        moveFile(new File(fileNameFrom), new File(fileNameTo));
    }

    /**
     * 创建临时目录
     *
     * @return
     */
    public static File createTempDirectory() {
        final String tmpPath = getTempDirectoryPath();
        long current = System.currentTimeMillis();
        File tmpDir = new File(tmpPath + File.separator + "patchDir" + current);
        if (tmpDir.exists()) {
            return tmpDir;
        }
        tmpDir.mkdirs();
        return tmpDir;
    }

    /**
     * 获取工程源文件所在路径
     * 
     * @return
     */
//    public static String getProjectPath() {
//        String projectPath = "";
//        try {
//            File file = ResourceUtils.getResource("").getFile();
//            if (file != null) {
//                while (true) {
//                    File f = new File(path(file.getPath() + "/src/main"));
//                    if (f.exists()) {
//                        break;
//                    }
//                    f = new File(path(file.getPath() + "/target/classes"));
//                    if (f.exists()) {
//                        break;
//                    }
//                    if (file.getParentFile() != null) {
//                        file = file.getParentFile();
//                    } else {
//                        break;
//                    }
//                }
//                projectPath = file.toString();
//            }
//        } catch (FileNotFoundException e) {
//            ;
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return projectPath;
//    }

    /**
     * 获取工程源文件所在路径
     * 
     * @return
     */
//    public static String getWebappPath() {
//        String webappPath = "";
//        try {
//            File file = ResourceUtils.getResource("").getFile();
//            if (file != null) {
//                while (true) {
//                    File f = new File(path(file.getPath() + "/WEB-INF/classes"));
//                    if (f.exists()) {
//                        break;
//                    }
//                    f = new File(path(file.getPath() + "/src/main/webapp"));
//                    if (f.exists()) {
//                        return f.getPath();
//                    }
//                    if (file.getParentFile() != null) {
//                        file = file.getParentFile();
//                    } else {
//                        break;
//                    }
//                }
//                webappPath = file.toString();
//            }
//        } catch (FileNotFoundException e) {
//            ;
//        } catch (IOException e) {
//            log.error("", e);
//        }
//        return webappPath;
//    }

}
